"""Change tracking for LDAP operations."""

import oldap.callback
from hcp import models

class HcpCallback(oldap.callback.LdapCallback):

    def __init__(self, username):
        self.username = username

    def post_add(self, model, modlist):
        m = models.Modification(username=self.username)
        m.save()
        mo = models.ModificationObject(mod=m,
                                       action='A',
                                       object_type=model.pretty_name,
                                       dn=model.dn)
        mo.save()
        for attribute_name, value in modlist:
            ma = models.ModificationAttribute(mod_obj=mo,
                                              attribute_name=attribute_name,
                                              op='A')
            ma.save()
            if not isinstance(value, (list, tuple)):
                value = [value]
            for v in value:
                mv = models.ModificationValueNew(mod_attr=ma,
                                                 value=v)
                mv.save()

    def post_rename(self, model, original_dn, new_dn):
        m = models.Modification(username=self.username)
        m.save()
        mo = models.ModificationObject(mod=m,
                                       action='R',
                                       object_type=model.pretty_name,
                                       db=model.dn)
        mo.save()
        ma = models.ModificationAttribute(mod_obj=mo,
                                          attribute_name='dn',
                                          op='M')
        ma.save()
        mvo = models.ModificationValueOld(mod_attr=ma,
                                          value=original_dn)
        mvo.save()
        mvn = models.ModificationValueNew(mod_attr=ma,
                                          value=new_dn)
        mvn.save()

    def post_modify(self, model, modlist):
        m = models.Modification(username=self.username)
        m.save()
        mo = models.ModificationObject(mod=m,
                                       action='M',
                                       object_type=model.pretty_name,
                                       dn=model.dn)
        mo.save()
        for mod_op, attribute_name, old_value, new_value in modlist:
            op = models.MOD_OP_MAP[mod_op]
            ma = models.ModificationAttribute(mod_obj=mo,
                                              attribute_name=attribute_name,
                                              op=op)
            ma.save()

            if not isinstance(old_value, (list, tuple)):
                old_value = [old_value]
            for value in old_value:
                mvo = models.ModificationValueOld(mod_attr=ma,
                                                  value=value)
                mvo.save()

            if not isinstance(new_value, (list, tuple)):
                new_value = [new_value]
            for value in new_value:
                mvn = models.ModificationValueNew(mod_attr=ma,
                                                  value=value)
                mvn.save()

    def post_delete(self, model):
        m = models.Modification(username=self.username)
        m.save()
        mo = models.ModificationObject(mod=m,
                                       action='D',
                                       object_type=model.pretty_name,
                                       dn=model.dn)
        mo.save()
